package com.ozten.reboot;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.ozten.reboot.icasualty.Soldier;

public class ICasualtiesReader {
	
	public static final String LOCAL_ICASUALTY_FEED;
	
	static {
		LOCAL_ICASUALTY_FEED = ResourceBundle.getBundle("resource").getString(
				"local.icasualty_feed");		
	}

	String[] fields;
	Pattern p;
	private String url;

	public ICasualtiesReader() {
		p = Pattern.compile(ResourceBundle.getBundle("resource").getString(
				"casualty.line"));
		loadFieldNames(ResourceBundle.getBundle("resource").getString(
				"casualty.field.names"));
		url = ResourceBundle.getBundle("resource").getString("icasualty.url");

		System.out.println("Reader will use " + url);
	}

	void loadFieldNames(String rawFieldNames) {
		String[] fieldNames = rawFieldNames.split(",");
		this.fields = new String[fieldNames.length];
		for (int i = 0; i < fieldNames.length; i++) {
			fields[i] = fieldNames[i].trim();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ICasualtiesReader casualties = new ICasualtiesReader();
		casualties.getUpdates();
	}

	public void getUpdates() {
		BufferedReader input = null;
		try {
			input = new BufferedReader(new InputStreamReader(
					new URL(url).openStream()));
			List<Soldier> casualties = parse(input);
			updateFeed(casualties, getFeedStream());
			// System.out);
		} catch (UnknownHostException e) {
			// User is offline
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	

	PrintStream getFeedStream() {
		try {
			return new PrintStream(LOCAL_ICASUALTY_FEED);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return System.err;
		}
	}

	void updateFeed(List<Soldier> casualties, PrintStream out) {
		System.out.println(Calendar.getInstance().getTime() + " - fetching updates");
		out
				.println("//Reformatted from http://icasualties.org/oif/Details.aspx");
		out.println("var coalition = {\"casualties\": [");
		int count = casualties.size();
		int i = 1;
		for (Soldier casualty : casualties) {
			out.print("  {");
			printData(out, "id", casualty.getId());
			out.print(", ");
			printData(out, "name", casualty.getName());
			out.print(", ");
			printData(out, "causeOfDeath", casualty.getCauseOfDeath());

			if (i < count) {
				out.println("}, ");
			} else {
				// The last one, and let it be the last
				out.println("}");
			}

			i++;
		}
		out.println("]};");
	}

	void printData(PrintStream out, String name, Object value) {
		out.print("\"" + name + "\":\"" + value + "\"");
	}

	public List<Soldier> parse(BufferedReader in) throws IOException {
		List<Soldier> casualties = new ArrayList<Soldier>(50);
		String line = in.readLine();
		while (line != null) {
			Matcher m = p.matcher(line);
			if (m.matches()) {
				int groupCount = m.groupCount();
				// TODO validate groupCount length and parse int / Dates before
				// using
				// for(int i=1; i<=groupCount; i++){
				if (m.groupCount() == 12) {
					Soldier casualty = new Soldier(getInt(m.group(1)),
							new Date(m.group(2)), m.group(3), m.group(4),
							getInt(m.group(5)), m.group(6), m.group(7), m
									.group(8), m.group(9), m.group(10), m
									.group(11), m.group(12));
					casualties.add(casualty);
				}
			}
			line = in.readLine();
		}
		return casualties;
	}

	public int getInt(String value) {
		try {
			return Integer.parseInt(value.replace("&nbsp;", " "));
		} catch (NumberFormatException e) {
			return 0;
		}
	}
}
